﻿/**********************************************************************
 * Copyright (c) 2008, j. montgomery                                  *
 * All rights reserved.                                               *
 *                                                                    *
 * Redistribution and use in source and binary forms, with or without *
 * modification, are permitted provided that the following conditions *
 * are met:                                                           *
 *                                                                    *
 * + Redistributions of source code must retain the above copyright   *
 *   notice, this list of conditions and the following disclaimer.    *
 *                                                                    *
 * + Redistributions in binary form must reproduce the above copyright*
 *   notice, this list of conditions and the following disclaimer     *
 *   in the documentation and/or other materials provided with the    *
 *   distribution.                                                    *
 *                                                                    *
 * + Neither the name of j. montgomery's employer nor the names of    *
 *   its contributors may be used to endorse or promote products      *
 *   derived from this software without specific prior written        *
 *   permission.                                                      *
 *                                                                    *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS*
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  *
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  *
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE     *
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,*
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES           *
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) *
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,*
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)      *
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED*
 * OF THE POSSIBILITY OF SUCH DAMAGE.                                 *
 **********************************************************************/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

using System.Configuration;
using System.Diagnostics;

using UpdateDnsOMatic.Enums;
using UpdateDnsOMatic.Utility;

namespace UpdateDnsOMatic.Configuration
{
    internal class DnsOMaticConfiguration
    {
        private static volatile DnsOMaticConfiguration _instance = new DnsOMaticConfiguration();
        private System.Configuration.Configuration _configuration;
        private bool _isDirty = false;

        // Singleton Reference to the Instance.
        public static DnsOMaticConfiguration Instance
        {
            get { return _instance; }
        }

        private DnsOMaticSection Section
        {
            get
            {
                // If section doesn't exist, create it
                if (_configuration.Sections[DnsOMaticSection.SECTION_NAME] == null)
                {
                    _isDirty = true;
                    this.CreateSection();
                }

                return (DnsOMaticSection)_configuration.Sections[DnsOMaticSection.SECTION_NAME];
            }
        }

        public string ServerAddress
        {
            get { return this.Section.ServerAddress; }
            set 
            { 
                this.Section.ServerAddress = value;
                _isDirty = true;
            }
        }

        public string LastKnownIP
        {
            get { return this.Section.LastKnownIP; }
            set
            {
                this.Section.LastKnownIP = value;
                _isDirty = true;
            }
        }

        public string PublicIpDiscoverServerAddress
        {
            get { return this.Section.PublicIpDiscoverServerAddress; }
            set { this.Section.PublicIpDiscoverServerAddress = value; }
        }

        [StringValidator(InvalidCharacters = "!@#$%^&*()+={}|[]\\:\";',/<>?`~", MinLength = 3, MaxLength = 25)]
        public string UserName
        {
            get { return this.Section.UserName; }
            set
            {
                this.Section.UserName = value;
                _isDirty = true;
            }
        }

        [StringValidator(InvalidCharacters = "!@#$%^&*()+={}|[]\\:\";',/<>?`~", MinLength = 6, MaxLength = 20)]
        public string Password
        {
            get
            {
                CryptoUtility crypto = new CryptoUtility();
                return crypto.DecryptData(this.Section.Password);
            }
            set
            {
                CryptoUtility crypto = new CryptoUtility();
                this.Section.Password = crypto.EncryptData(value);
                _isDirty = true;

            }
        }
        public string HostNameToUpdate
        {
            get { return this.Section.HostNameToUpdate; }
            set { this.Section.HostNameToUpdate = value; }
        }

        public string Wildcard
        {
            get { return this.Section.Wildcard; }
            set { this.Section.Wildcard = value; }
        }

        public string MX
        {
            get { return this.Section.MX; }
            set { this.Section.MX = value; }
        }

        public string BackupMX
        {
            get { return this.Section.BackupMX; }
            set { this.Section.BackupMX = value; } 
        }

        public UpdateInterval Interval
        {
            get { return this.Section.Interval; }
            set { this.Section.Interval = value; }
        }
        // Singleton Constructor
        private DnsOMaticConfiguration()
        {
            // Get the current configuration file.
            _configuration = ConfigurationManager.OpenExeConfiguration(
                    ConfigurationUserLevel.None);
        }


        // Create the IntegraLinkSection in the App config file with Default values.
        internal void CreateSection()
        {
            try
            {
                // Create the section entry  
                // in <configSections> and the 
                // related target section in <configuration>.
                if (_configuration.Sections[DnsOMaticSection.SECTION_NAME] == null)
                {
                    DnsOMaticSection integraLinkSection = new DnsOMaticSection();
                    _configuration.Sections.Add(DnsOMaticSection.SECTION_NAME, integraLinkSection);

                    this.Save();

                    Trace.WriteLine(String.Format("Section name: {0} created.",
                        integraLinkSection.SectionInformation.Name));
                }
            }
            catch (ConfigurationErrorsException err)
            {
                Trace.WriteLine(err.ToString());
            }
        }

        public void Save()
        {
            if (_isDirty)
            {
                try
                {
                    _configuration.Sections[DnsOMaticSection.SECTION_NAME].SectionInformation.ForceSave = true;
                    _configuration.Save(System.Configuration.ConfigurationSaveMode.Full);
                    _isDirty = false;
                }
                catch (ConfigurationErrorsException cee)
                {
                    Trace.WriteLine("Unable to save data to configuration file: " + cee.ToString());
                }
            }
        }
    }
}
